
#ifndef etl_socket_h
#define etl_socket_h

#ifdef WIN32
#include <winsocmf.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>
#endif

#include "etl_string.h"

#include "pthread.h"

namespace etl
{

typedef int (*timeout_cb)( void* opaque );

#define DEFAULT_RECV_TIMEOUT 5000

class etl_socket
{
public:
  enum etl_socket_enum
    {
      SOK_SUCCESS = 0,
      SOK_FAILURE = -1
    };
  
  etl_socket();
  virtual ~etl_socket();
  
  int create();
  int get_sok_id();
  int bind(int port);
  int listen();
  int accept( etl_socket& new_etl_socket );
  int connect( etl_string host, int port );
  int shutdown( int mode );
  int send( const void* msg, ssize_t msg_len );
  int recv( void* buf, ssize_t buf_len );
  ssize_t raw_send( const void* msg, size_t msg_len );
  ssize_t raw_recv( void* buf, size_t buf_len );
  int attach_recv_timeout_handler( timeout_cb rtcb, void* opaque );
  int set_recv_timeout( size_t milliseconds );
  int attach_send_timeout_handler( timeout_cb stcb, void* opaque );
  int set_send_timeout( size_t milliseconds );
  bool ready_to_recv( size_t milliseconds );
  bool ready_to_send( size_t milliseconds );
  int wait_recv();
  int wait_send();

private:
  int             sok;
  sockaddr_in     addr;
  size_t          recv_timeout_milliseconds;
  timeout_cb      recv_timeout_handler;
  void*           recv_timeout_handler_opaque;
  size_t          send_timeout_milliseconds;
  timeout_cb      send_timeout_handler;
  void*           send_timeout_handler_opaque;
};

}

#endif
